home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / pp / pp-6.0 / Lib / charset / strcnv.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-12-18  |  7.7 KB  |  432 lines

  1. /* strcnv.c 1.4 901228 */
  2.  
  3. # ifndef lint
  4. static char Rcsid[] = "@(#)$Header: /xtel/pp/pp-beta/Lib/charset/RCS/strcnv.c,v 6.0 1991/12/18 20:21:39 jpo Rel $";
  5. # endif
  6.  
  7. /*
  8.  * $Header: /xtel/pp/pp-beta/Lib/charset/RCS/strcnv.c,v 6.0 1991/12/18 20:21:39 jpo Rel $
  9.  *
  10.  * $Log: strcnv.c,v $
  11.  * Revision 6.0  1991/12/18  20:21:39  jpo
  12.  * Release 6.0
  13.  *
  14.  */
  15.  
  16.  
  17.  
  18. #include    "util.h"
  19. #include    <fcntl.h>
  20. #include    <ctype.h>
  21. #include    "charset.h"
  22.  
  23.  
  24. extern char    *charset_dir, *charset_mnem;
  25.  
  26. static IN_CH    *chset = NULL;
  27. static CHARSET    *charsets = NULL;
  28.  
  29.  
  30.  
  31. /* -- local routines -- */
  32. static CHAR8U    *getoutch();
  33. static INT16S    *getinch();
  34. static int    findc();
  35. static int    getchbas();
  36. static int    openfile();
  37. extern off_t lseek ();
  38.  
  39. static int    strcnv_mnemonics(), strncnv_mnemonics(),
  40.     strncnv_x408();
  41.  
  42.  
  43.  
  44. /* -------------------- Begin  Routines  ------------------------------------ */
  45.  
  46.  
  47.  
  48.  
  49. int strcnv (r_chset, s_chset, result, source, MnemonicsRequired)
  50. CHARSET    *r_chset;
  51. CHARSET *s_chset;
  52. CHAR8U    *result;
  53. CHAR8U    *source;
  54. int    MnemonicsRequired;
  55. {
  56.     switch (MnemonicsRequired) {
  57.     case TRUE:
  58.         return (strcnv_mnemonics (r_chset, s_chset, result, source));
  59.     default:
  60.         return (-1);
  61.     }
  62. }
  63.  
  64.  
  65.  
  66.  
  67. int strncnv (r_chset, s_chset, result, source, n, MnemonicsRequired)
  68. CHARSET *r_chset;
  69. CHARSET *s_chset;
  70. CHAR8U    *result;
  71. CHAR8U    *source;
  72. int    n;
  73. int    MnemonicsRequired;
  74. {
  75.     switch (MnemonicsRequired) {
  76.     case TRUE:
  77.         return (strncnv_mnemonics 
  78.                 (r_chset, s_chset, result, source, n));
  79.     default:
  80.         return (strncnv_x408 
  81.                 (r_chset, s_chset, result, source, n));
  82.     }
  83. }
  84.  
  85.  
  86.  
  87.  
  88. CHARSET *getchset (s, esc)
  89. char    *s;
  90. INT16S    esc;
  91. {
  92.     register CHARSET    *c, *c1;
  93.     register char    *p;
  94.  
  95.     for (p = s; *p; p++) 
  96.         if (isascii (*p) && islower (*p)) 
  97.             *p = toupper (*p);
  98.     if (getchbas() == 0) 
  99.         return NULL;
  100.     for (c = charsets; c && strcmp (c->name, s); c = c->next) 
  101.         c1 = c;
  102.     if (!c) {
  103.         c = (CHARSET * ) malloc (sizeof (CHARSET));
  104.         if (!c) 
  105.             return NULL;
  106.         c->next = NULL;
  107.         c->out = getoutch (s, (CHAR8U)0);
  108.         if (c->out) {
  109.             c->name = (char *) strdup (s);
  110.             c->in = getinch (s, (CHAR8U)0);
  111.             c->esc = esc;
  112.         } else { 
  113.             free ((char *)c); 
  114.             c = NULL; 
  115.         }
  116.         if (charsets) 
  117.             c1->next = c; 
  118.         else 
  119.             charsets = c;
  120.     }
  121.     return c;
  122. }
  123.  
  124.  
  125.  
  126.  
  127. /* -------------------------  Static  Routines  ---------------------------- */
  128.  
  129.  
  130.  
  131.  
  132. static int strcnv_mnemonics (r_chset, s_chset, result, source)
  133. CHARSET    *r_chset;
  134. CHARSET *s_chset;
  135. CHAR8U    *result;
  136. CHAR8U    *source;
  137. {
  138.     register CHAR8U        *p, *q;
  139.     register CHAR8U        *out;
  140.     register INT16S        *in;
  141.     register int        o;  /* intermediate binary value */
  142.     register int        c;
  143.     register INT16S        esc, esco, mnem;
  144.  
  145.     p = result; 
  146.     q = source;
  147.     out = r_chset->out; 
  148.     in = s_chset->in;
  149.     esco = r_chset->esc; 
  150.     esc = s_chset->esc;
  151.  
  152.     while (c = *q++) {
  153.         /* printf (" %c %c %c",c,*q,esc);  */
  154.         if (c == esc) {
  155.             /* two esc in a row -> one escape */
  156.             /* if esc followed by defined mnemonic
  157.                next char is mnemonic. */
  158.  
  159.             if (*q == esc) { 
  160.                 o = in[esc]; 
  161.                 q++; 
  162.             } else { 
  163.                 o = findc (q[0] * C256 + q[1]); 
  164.                 q += 2;
  165.             }
  166.         } else 
  167.             o = in[c];
  168.         if (!o) 
  169.             o = LOW_LINE; /* if illegal input replace with '_' */
  170.  
  171.         /* printf (" %d %d %c",o,esco,esco);  */
  172.         if (out[o] == esco) { 
  173.             *p++ = esco; 
  174.             *p++ = esco; 
  175.         } else if (out[o]) 
  176.             *p++ = out[o];
  177.         else {
  178.             mnem = chset[o];
  179.             *p++ = esco;
  180.             *p++ = out [in [mnem / C256 ]];
  181.             *p++ = out [in [mnem % C256 ]];
  182.         }
  183.     }
  184.     *p = '\0';
  185.     return p - result;
  186. }
  187.  
  188.  
  189.  
  190.  
  191. static int strncnv_mnemonics (r_chset, s_chset, result, source, n)
  192. CHARSET *r_chset;
  193. CHARSET *s_chset;
  194. CHAR8U    *result, *source;
  195. int    n;
  196. {
  197.     register CHAR8U        *p, *q, *e;
  198.     register CHAR8U        *out;
  199.     register INT16S        *in;
  200.     register int        o;  /* intermediate binary value */
  201.     register int        c;
  202.     register INT16S        esc, esco, mnem;
  203.  
  204.     p = result; 
  205.     q = source;
  206.     e = p + n - 4; /* 4 chars for ending: esc two-char nul */
  207.     out = r_chset->out; 
  208.     in = s_chset->in;
  209.     esco = r_chset->esc; 
  210.     esc = s_chset->esc;
  211.  
  212.     while ((c = *q++) && p < e) {
  213.         /* printf (" %c %c %c",c,*q,esc);   */
  214.         if (c == esc) {
  215.             /* two esc in a row -> one escape */
  216.             /* if esc followed by defined mnemonic
  217.                next char is mnemonic. */
  218.  
  219.             if (*q == esc) { 
  220.                 o = in[esc]; 
  221.                 q++; 
  222.             } else { 
  223.                 o = findc (q[0] * C256 + q[1]); 
  224.                 q += 2;
  225.             }
  226.         } else 
  227.             o = in[c];
  228.         if (!o) 
  229.             o = LOW_LINE; /* if illegal input replace with '_' */
  230.  
  231.         /* printf (" %d %d %c",o,esco,esco);  */
  232.         if (out[o] == esco) { 
  233.             *p++ = esco; 
  234.             *p++ = esco; 
  235.         } else if (out[o]) 
  236.             *p++ = out[o];
  237.         else {
  238.             mnem = chset[o];
  239.             *p++ = esco;
  240.             *p++ = out [in [mnem / C256 ]];
  241.             *p++ = out [in [mnem % C256 ]];
  242.         }
  243.     }
  244.     *p = '\0';
  245.     return p - result;
  246. }
  247.  
  248.  
  249.  
  250.  
  251. static int strncnv_x408 (r_chset, s_chset, result, source, n)
  252. CHARSET    *r_chset;
  253. CHARSET    *s_chset;
  254. CHAR8U    *result, *source;
  255. int    n;
  256. {
  257.     register CHAR8U     *p, *q, *e;
  258.     register CHAR8U        *out;
  259.     register INT16S        *in;
  260.     register int        o;  /* intermediate binary value */
  261.     register int        c;
  262.  
  263.     p = result;
  264.     q = source;
  265.     e = q + n;
  266.     out = r_chset->out; 
  267.     in = s_chset->in;
  268.  
  269.     /* --- *** ---
  270.     1) No mnemonics are used for unknown symbols.
  271.         They are just replaced with '?'. Provided they are NOT 
  272.         accented letters or umlauts. 
  273.     2) Accented letters or umlauts are 2 bit combinations: 
  274.         the first is a a mark, the second a basic Latin character. 
  275.         In this case only the character is printed.
  276.     --- *** --- */
  277.  
  278.     for (c = *q++; q <= e; c = *q++) {
  279.         o = in[c];
  280.         if (!o)
  281.             o = QUESTION_MARK;
  282.             /* if illegal input replace with '?' */
  283.  
  284.         if (out[o]) 
  285.             *p++ = out[o];
  286.         else if (c >= 192 && c <= 207) /* an accent ? */
  287.             if ((q[0] >= 'A' && q[0] <= 'Z') ||
  288.                 (q[0] >= 'a' && q[0] <= 'z'))
  289.                 continue;    
  290.             else
  291.                 *p++ = out[QUESTION_MARK];
  292.         else
  293.             *p++ = out[QUESTION_MARK];
  294.     }
  295.  
  296.     *p = '\0';
  297.     return p - result;
  298. }
  299.  
  300.  
  301.  
  302.  
  303. static int findc (c)
  304. register unsigned int    c; /* c is ascii value of two-byte char mnem */
  305. {
  306.     register INT16S *cs;
  307.     register int    i;
  308.  
  309.     i = chset[0] + 1;
  310.     cs = &chset[i];
  311.     while (--i > 0 && c != *--cs)
  312.         ;
  313.  
  314.     /* printf (" %d ",i); */
  315.     return i;  /* zero == not found */
  316. }
  317.  
  318.  
  319.  
  320.  
  321. static int openfile (dir, file, mode)
  322. char    *dir, *file;
  323. int    mode;
  324. {
  325.     char    fn[LSIZE];
  326.     register char    *p, *q;
  327.     register int    f;
  328.  
  329.     (void) strcpy (fn, dir);
  330.     (void) strcat (fn, "/");
  331.  
  332.     q = fn + strlen (fn);
  333.     for (p = file; *p; p++)
  334.         *q++ = (isascii (*p) && islower (*p))
  335.          ? toupper (*p) : *p;
  336.     *q = 0;
  337.  
  338.     f = open (fn, mode);
  339.     if (f < 0) 
  340.         (void) fprintf (stderr, "\n\n*** Error: opening file %s\n", fn);
  341.     return f;
  342. }
  343.  
  344.  
  345.  
  346.  
  347. static int getchbas()
  348. {
  349.     INT16S        sz[2];
  350.     register int    f;
  351.     unsigned    sz1;
  352.  
  353.     if (!chset) {
  354.         f = openfile (charset_dir, charset_mnem, O_RDONLY);
  355.         if (f < 0) 
  356.             return NULL;
  357.         if (read (f, (char *)sz, sizeof (INT16S)) != sizeof (INT16S)) 
  358.             goto err;
  359.         sz1 = sz[0] * sizeof (INT16S);
  360.         (void) lseek (f, 0L, 0);
  361.         if ((chset = (IN_CH * ) malloc (sz1)) == NULL) 
  362.             goto err;
  363.         if (read (f, (char *)chset, (int)sz1) != sz1) 
  364.             goto err;
  365.         /* printf ("charsz %d chars %22.22s\n",sz1,chset); */
  366.         (void) close (f);
  367.     }
  368.     return 1;
  369.  
  370. err:
  371.     (void) close (f);
  372.     return NULL;
  373. }
  374.  
  375.  
  376.  
  377.  
  378. static INT16S *getinch (charset, c)
  379. char    *charset;
  380. CHAR8U    c;
  381. {
  382.     int    f, sz;
  383.     IN_CH     * in;
  384.  
  385.     sz = C256 * sizeof (IN_CH);
  386.     in = (IN_CH * ) malloc ((unsigned)sz);
  387.     if (!in) 
  388.         return NULL;
  389.     f = openfile (charset_dir, charset, O_RDONLY);
  390.     if (f < 0) 
  391.         return NULL;
  392.     if (read (f, (char *)in, sz) != sz) { 
  393.         (void) close (f); 
  394.         return NULL; 
  395.     }
  396.     (void) close (f);
  397.     in[0] = c;
  398.     /*  printf (" %c %d ",c,in[0]);     */
  399.     return in;
  400. }
  401.  
  402.  
  403.  
  404.  
  405. static CHAR8U *getoutch (charset, c)
  406. char    *charset;
  407. CHAR8U    c;
  408. {
  409.     int    f;
  410.     unsigned    sz1;
  411.     OUT_CH         * out;
  412.  
  413.     if (getchbas() == 0) 
  414.         return NULL;
  415.     sz1 = chset[0];
  416.     f = openfile (charset_dir, charset, O_RDONLY);
  417.     if (f < 0) 
  418.         return NULL;
  419.     (void) lseek (f, C256L * sizeof (INT16S), 0);
  420.     out = (OUT_CH * ) malloc (sz1);
  421.     if (!out) 
  422.         goto err;
  423.     if (read (f, (char *)out, (int)sz1) != sz1) 
  424.         goto err;
  425.     (void) close (f);
  426.     out[0] = c;
  427.     return out;
  428. err:
  429.     (void) close (f);
  430.     return NULL;
  431. }
  432.